package com.shf.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.shf.constants.SystemCanstants;
import com.shf.domain.ResponseResult;
import com.shf.domain.entity.Comment;
import com.shf.domain.vo.CommentVo;
import com.shf.domain.vo.PageVo;
import com.shf.enums.AppHttpCodeEnum;
import com.shf.enums.SystemException;
import com.shf.mapper.CommentMapper;
import com.shf.service.CommentService;
import com.shf.service.UserService;
import com.shf.util.BeanCopyUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.Comparator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 叶枫
 * @date 2023/11/4.
 */

@Service("commentService")
public class CommentServiceImpl extends ServiceImpl<CommentMapper, Comment> implements CommentService {

    @Autowired
    private UserService userService;

    /**
     *   id 代表根评论   rootId 为 -1 的时跟评论  剩下的 rootId 对应着 各自根评论的 id
     * @param articleId
     * @param pageNum
     * @param pageSize
     * @return
     */
    @Override
    public ResponseResult commentList(String commentType, Long articleId, Integer pageNum, Integer pageSize) {

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();

        //对articleId进行判断，作用是得到指定的文章。如果是文章评论，才会判断articleId，避免友链评论判断articleId时出现空指针
        queryWrapper.eq(SystemCanstants.ARTICLE_COMMENT.equals(commentType),Comment::getArticleId,articleId);
        //判断 articleId的文章是否存在
        queryWrapper.eq(Comment::getArticleId,articleId);
        //查询根评论 判断rootid
        queryWrapper.eq(Comment::getRootId,-1);


        //分页
        Page<Comment> page1 = new Page<>(pageNum, pageSize);
        page(page1,queryWrapper);

        //按照时间排序
        //调用下面那个方法。根评论排序
        List<Comment> sortedComments = page1.getRecords().stream()
                .sorted(Comparator.comparing(Comment::getCreateTime).reversed())
                .collect(Collectors.toList());
        List<CommentVo> commentVoList = getCommentVoList(sortedComments);
        //查询子评论
        for (CommentVo commentVo : commentVoList) {

           List<CommentVo> children = getChildren(commentVo.getId());
           commentVo.setChildren(children);
        }

        return ResponseResult.okResult(new PageVo(commentVoList,page1.getTotal()));
    }

    @Override
    public ResponseResult addComment(Comment comment) {

        //注意前端在调用这个发送评论接口时，在请求体是没有向我们传入createTime、createId、updateTime、updateID字段，所以
        //我们这里往后端插入数据时，就会导致上面那行的四个字段没有值
        //为了解决这个问题，我们在huanf-framework工程新增了MyMetaObjectHandler类、修改了Comment类。详细可自己定位去看一下代码

        if (!StringUtils.hasText(comment.getContent())){
            throw  new SystemException(AppHttpCodeEnum.CONTENT_NOT_NULL);
        }

        save(comment);
        //封装响应返回
        return ResponseResult.okResult();
    }

    /**
     *
     * @param id 跟评论的id
     * @return
     */
    private List<CommentVo> getChildren(Long id) {

        LambdaQueryWrapper<Comment> queryWrapper = new LambdaQueryWrapper<>();

        queryWrapper.eq(Comment::getRootId ,id);
        queryWrapper.orderByDesc(Comment::getCreateTime);

        List<Comment> list = list(queryWrapper);
        List<CommentVo> commentVos = getCommentVoList(list);
        return commentVos;

    }


    private List<CommentVo> getCommentVoList(List<Comment>list){
        List<CommentVo> commentVos = BeanCopyUtils.copyBeanList(list, CommentVo.class);
        List<CommentVo> commentVoList = commentVos.stream()
                .map(commentVo -> {
                    //需要根据commentVo类里面的createBy字段，然后用createBy字段去查询user表的nickname字段(子评论的用户昵称)
                    String nickName = userService.getById(commentVo.getCreateBy()).getNickName();
                    //然后把nickname字段(发这条子评论的用户昵称)的数据赋值给commentVo类的username字段
                    commentVo.setUsername(nickName);
                    //查询根评论的用户昵称。怎么判断是根评论的用户呢，判断getToCommentUserId为-1，就表示这条评论是根评论
                    if(commentVo.getToCommentUserId() != -1){
                        String toCommentUserName = userService.getById(commentVo.getToCommentUserId()).getNickName();
                        //然后把nickname字段(发这条根评论的用户昵称)的数据赋值给commentVo类的toCommentUserName字段
                        commentVo.setToCommentUserName(toCommentUserName);
                    }
                    return commentVo;
                })
                .collect(Collectors.toList());

        return commentVoList;
    }
}
